package com.baidu.ueditor;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import com.baidu.ueditor.define.ActionMap;
import com.daffodil.util.JacksonUtils;
import com.google.common.base.Charsets;

/**
 * 配置管理器
 * 
 * @author yweijian
 * @date 2021年2月7日
 * @version 1.0
 * @description
 */
public final class ConfigManager {
	
	private final String rootPath;
	private HashMap<String, Object> jsonConfig = null;
	
	// 涂鸦上传filename定义
	private final static String SCRAWL_FILE_NAME = "scrawl";
	// 远程图片抓取filename定义
	private final static String REMOTE_FILE_NAME = "remote";

	/**
	 * 配置管理器构造工厂
	 * 
	 * @param configPath    json配置文件的路径
	 * @param rootPath      文件存储的路径
	 * @return 配置管理器实例或者null
	 */
	public static ConfigManager getInstance(String configPath, String rootPath) {
		return new ConfigManager(configPath, rootPath);
	}

	// 验证配置文件加载是否正确
	public boolean valid() {
		return this.jsonConfig != null;
	}

	public String getAllConfig() {
		return JacksonUtils.toJSONString(this.jsonConfig, true);
	}

	public Map<String, Object> getConfig(int type) {

		Map<String, Object> conf = new HashMap<String, Object>();
		String savePath = null;

		switch (type) {

		case ActionMap.UPLOAD_FILE:
			conf.put("isBase64", "false");
			conf.put("maxSize", JacksonUtils.getAsLong(this.jsonConfig, "fileMaxSize"));
			List<?> fileAllowFiles = JacksonUtils.getAsList(this.jsonConfig, "fileAllowFiles");
			conf.put("allowFiles", fileAllowFiles != null ? fileAllowFiles.toArray(new String[fileAllowFiles.size()]) : new String[0]);
			conf.put("fieldName", JacksonUtils.getAsString(this.jsonConfig, "fileFieldName"));
			savePath = JacksonUtils.getAsString(this.jsonConfig, "filePathFormat");
			break;

		case ActionMap.UPLOAD_IMAGE:
			conf.put("isBase64", "false");
			conf.put("maxSize", JacksonUtils.getAsLong(this.jsonConfig, "imageMaxSize"));
			List<?> imageAllowFiles = JacksonUtils.getAsList(this.jsonConfig, "imageAllowFiles");
			conf.put("allowFiles", imageAllowFiles != null ? imageAllowFiles.toArray(new String[imageAllowFiles.size()]) : new String[0]);
			conf.put("fieldName", JacksonUtils.getAsString(this.jsonConfig, "imageFieldName"));
			savePath = JacksonUtils.getAsString(this.jsonConfig, "imagePathFormat");
			break;

		case ActionMap.UPLOAD_VIDEO:
			conf.put("maxSize", JacksonUtils.getAsLong(this.jsonConfig, "videoMaxSize"));
			List<?> videoAllowFiles = JacksonUtils.getAsList(this.jsonConfig, "videoAllowFiles");
			conf.put("allowFiles", videoAllowFiles != null ? videoAllowFiles.toArray(new String[videoAllowFiles.size()]) : new String[0]);
			conf.put("fieldName", JacksonUtils.getAsString(this.jsonConfig, "videoFieldName"));
			savePath = JacksonUtils.getAsString(this.jsonConfig, "videoPathFormat");
			break;

		case ActionMap.UPLOAD_SCRAWL:
			conf.put("isBase64", "true");
			conf.put("filename", ConfigManager.SCRAWL_FILE_NAME);
			conf.put("maxSize", JacksonUtils.getAsLong(this.jsonConfig, "scrawlMaxSize"));
			conf.put("fieldName", JacksonUtils.getAsString(this.jsonConfig, "scrawlFieldName"));
			savePath = JacksonUtils.getAsString(this.jsonConfig, "scrawlPathFormat");
			break;

		case ActionMap.CATCH_IMAGE:
			conf.put("filename", ConfigManager.REMOTE_FILE_NAME);
			List<?> catcherLocalDomain = JacksonUtils.getAsList(this.jsonConfig, "catcherLocalDomain");
			conf.put("filter", catcherLocalDomain != null ? catcherLocalDomain.toArray(new String[catcherLocalDomain.size()]) : new String[0]);
			conf.put("maxSize", JacksonUtils.getAsLong(this.jsonConfig, "catcherMaxSize"));
			List<?> catcherAllowFiles = JacksonUtils.getAsList(this.jsonConfig, "catcherAllowFiles");
			conf.put("allowFiles", catcherAllowFiles != null ? catcherAllowFiles.toArray(new String[catcherAllowFiles.size()]) : new String[0]);
			conf.put("fieldName", JacksonUtils.getAsString(this.jsonConfig, "catcherFieldName") + "[]");
			savePath = JacksonUtils.getAsString(this.jsonConfig, "catcherPathFormat");
			break;

		case ActionMap.LIST_IMAGE:
			List<?> imageManagerAllowFiles = JacksonUtils.getAsList(this.jsonConfig, "imageManagerAllowFiles");
			conf.put("allowFiles", imageManagerAllowFiles != null ? imageManagerAllowFiles.toArray(new String[imageManagerAllowFiles.size()]) : new String[0]);
			conf.put("dir", JacksonUtils.getAsString(this.jsonConfig, "imageManagerListPath"));
			conf.put("count", JacksonUtils.getAsInteger(this.jsonConfig, "imageManagerListSize"));
			break;

		case ActionMap.LIST_FILE:
			List<?> fileManagerAllowFiles = JacksonUtils.getAsList(this.jsonConfig, "fileManagerAllowFiles");
			conf.put("allowFiles", fileManagerAllowFiles != null ? fileManagerAllowFiles.toArray(new String[fileManagerAllowFiles.size()]) : new String[0]);
			conf.put("dir", JacksonUtils.getAsString(this.jsonConfig, "fileManagerListPath"));
			conf.put("count", JacksonUtils.getAsInteger(this.jsonConfig, "fileManagerListSize"));
			break;

		}
		conf.put("savePath", savePath);
		conf.put("rootPath", this.rootPath);

		return conf;

	}
	
	@SuppressWarnings("unchecked")
	private ConfigManager(String configPath, String rootPath){
		
		rootPath = rootPath.replace("\\", "/");
		this.rootPath = rootPath;
		
		try {
			String configContent = this.readFile(configPath);
			HashMap<String, Object> jsonConfig = JacksonUtils.toJavaObject(configContent, HashMap.class);
			this.jsonConfig = jsonConfig;
		} catch (Exception e) {
			this.jsonConfig = null;
		}
	}

	private String readFile(String path) throws IOException {
		String configContent = "{}";
		if(path.contains("classpath:")) {
			Resource resource = new ClassPathResource(path.replace("classpath:", ""));
			configContent = IOUtils.toString(new FileInputStream(resource.getFile()), Charsets.UTF_8.toString());
		}else {
			configContent = IOUtils.toString(new FileInputStream(new File(path)), Charsets.UTF_8.toString());
		}
		// 过滤输入字符串, 剔除多行注释以及替换掉反斜杠
		return configContent.replaceAll("/\\*[\\s\\S]*?\\*/", "");
	}

}
